﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.IO.Compression;

namespace Ex3.ZipUnzipBinaries
{
    class ZipUnzipBinaries
    {
        public static string FILE_NAME_IN = "..\\..\\test.bin";
        public static string FILE_NAME_OUT = "..\\..\\test.zip";

        public static bool CompressFile(string file, string outputFile)
        {
            try
            {
                using (var inFile = File.OpenRead(file))
                {
                    using (var outFile = File.Create(outputFile))
                    {
                        //now create a GZipStream object for writing the input file to
                        using (var compress = new GZipStream(outFile, CompressionMode.Compress, false))
                        {
                            //buffer array to hold the input file in
                            byte[] buffer = new byte[inFile.Length];

                            //read the file into the FileStream
                            int read = inFile.Read(buffer, 0, buffer.Length);

                            //now loop (as long as we have data) and
                            //write to the GZipStream
                            while (read > 0)
                            {
                                compress.Write(buffer, 0, read);
                                read = inFile.Read(buffer, 0, buffer.Length);
                            }
                        }
                    }
                }
                return true;
            }
            catch (IOException ex)
            {
                Console.WriteLine(string.Format("Error compressing file: {0}", ex.Message));
                return false;
            }
        }

        public static bool Decompress(string source, string destFile)
        {
            try
            {
                using (var inStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    using (var outStream = new FileStream(destFile, FileMode.Create, FileAccess.Write, FileShare.None))
                    {
                        using (var zipStream = new GZipStream(inStream, CompressionMode.Decompress, true))
                        {
                            //byte arrya the size of our input file
                            byte[] buffer = new byte[inStream.Length];

                            while (true)
                            {
                                int count = zipStream.Read(buffer, 0, buffer.Length);

                                if (count != 0)
                                    outStream.Write(buffer, 0, count);

                                if (count != buffer.Length)
                                {
                                    // have reached the end
                                    break;
                                }
                            }
                        }
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(string.Format("Error decompressing file {0}: {1}", source, ex.Message));
                return false;
            }
        }

        public static void CreateFile(string fileName)
        {
            File.Create(fileName).Dispose();
        }

        static void Main(string[] args)
        {
            //CreateFile(FILE_NAME);
            bool hasCompressed = CompressFile(FILE_NAME_IN, FILE_NAME_OUT);
            if (hasCompressed)
            {
                Console.WriteLine("File Compressed!");
            }
        }
    }
}
